<?php
require_once("DbFactory.class.php");
require_once(ROOT . "/lib/Pagination.class.php");
abstract class Base
{
    protected $_db;
    protected $_pageSize;
    protected $_pagination;
    protected $_count;
    protected $_pagination_sql;
    protected $_pagination_count_sql;
    protected $_status_field_name = "status";

    abstract protected function getPrimaryKey();

    abstract protected function getTableName();

    public function delete($id)
    {
        $sql = "delete from " . $this->getTableName() . " where " . $this->getPrimaryKey() . "=" . $id;
        return $this->_db->delete($sql);
    }

    public function remove($id)
    {
        return $this->updateStatus($id, "D");
    }

    public function updateStatus($id, $status)
    {
        $sql = "update " . $this->getTableName() . " set " . $this->_status_field_name . "='" . $status . "' where " . $this->getPrimaryKey() . "=" . $id;
        return $this->_db->update($sql);
    }

    public function load($id)
    {
        $sql = "select * from " . $this->getTableName() . " where " . $this->getPrimaryKey() . "='" . $id . "'";
        return $this->_db->getOne($sql);
    }

    public function loadAsObject($id)
    {
        $this->mapping($this->load($id));
        return $this;
    }

    protected function competeRecord($post)
    {
        return null;
    }

    public function insert($post)
    {
        return $this->_db->createRecord($this->getTableName(), $this->competeRecord($post)) > 0;
    }

    public function update($post)
    {
        $record = $this->competeRecord($post);
        $record[$this->getPrimaryKey()] = $post[$this->getPrimaryKey()];
        return $this->_db->updateRecord($this->getTableName(), $record, $this->getPrimaryKey()) > 0;
    }

    public function __construct()
    {
        $this->_db = DbFactory::getDbDriver();
    }

    public function setDb($db)
    {
        $this->_db = $db;
    }

    public function getDb()
    {
        return $this->_db;
    }

    public function __call($method, $parameter)
    {
        throw new ErrorException("the method not found" . $method);
    }

    protected function mapping($result)
    {
        if ($result[$this->getPrimaryKey()] == null) throw new ErrorException("mapping failure");

        foreach ($result as $key => $value) {
            try {
                call_user_func(array($this, "set" . ucfirst($key)), $value);
            } catch (ErrorException $e) {
                continue;
            }

        }
    }

    public function pagination($paginationSql, $pagination_count_sql, $pageSize = 10)
    {
        $this->_pageSize = $pageSize;
        $this->_pagination_sql = $paginationSql;
        $this->_pagination_count_sql = $pagination_count_sql;
        $count = $this->_db->getOne($this->_pagination_count_sql);
        $this->_count = $count['count'];
        $this->_pagination = new Pagination(array('total' => $this->_count, 'perpage' => $this->_pageSize));
        $offset = ($this->_pagination->nowindex - 1) * $this->_pageSize;
        $result = array(
            "totalCount" => $this->_count,
            "code" => $this->_pagination->show(4),
            "data" => $this->_db->getall($this->_pagination_sql . " limit " . $offset . "," . $this->_pageSize)
        );
        return $result;

    }

    public function loadModule($moduleName)
    {
        include_once("Base.class.php");
        include_once($moduleName . ".class.php");
        return new $moduleName;
    }

    public function getCredentials()
    {
        return $_SESSION['credentials'];
    }

    function __destruct()
    {
        $this->_db = null;
        // TODO: Implement __destruct() method.
    }

    public function query($sql)
    {
        $this->_db->query($sql);
    }


}

?>